<?php

namespace app\common\model\banxi\course;

use app\common\enums\CourseDataTypeEnum;
use app\common\enums\QuestionTypeEnum;
use app\common\model\common\BaseModel;
use ba\Exception;
use think\db\exception\PDOException;
use think\exception\ValidateException;
use think\model\concern\SoftDelete;

/*
 * 题目
 * */

class CourseQuestion extends BaseModel
{
    use SoftDelete;

    protected $name = 'banxi_course_question';

    protected $autoWriteTimestamp = true;

    protected $deleteTime = 'del';

    protected $defaultSoftDelete = 0;

    protected $append = [
        'dataTypeCn',
        'questionTypeCn',
        'answerList',
        'optionList'
    ];

    protected $type = [
        'id' => 'string',
        'del' => 'string',
        'courseId' => 'string',
        'dataId' => 'string',
        'sortNum' => 'string',
        'createTime' => 'timestamp:Y-m-d H:i:s',
        'updateTime' => 'timestamp:Y-m-d H:i:s',
    ];

    //-----------------------------------------------------------------------------------
    //｜                                   获取器                                         ｜
    //-----------------------------------------------------------------------------------

    public function getDataTypeCnAttr($value, $data)
    {
        $value = $value ?: ($data['dataType'] ?? '');
        return (new CourseDataTypeEnum())->getDescription($value) ?? '';
    }

    public function getQuestionTypeCnAttr($value, $data)
    {
        $value = $value ?: ($data['questionType'] ?? '');
        return (new QuestionTypeEnum())->getDescription($value) ?? '';
    }

    public function getAnswerListAttr($value, $data)
    {
        $value = $value ?: ($data['answer'] ?? '');
        return $value ? json_decode($value, true) : [];
    }

    public function getOptionListAttr($value, $data)
    {
        $value = $value ?: ($data['option'] ?? '');
        return $value ? json_decode($value, true) : [];
    }

    //-----------------------------------------------------------------------------------
    //｜                                   处理方法                                       ｜
    //----------------------------------------------------------------------------------


    public function removeByData(array $dataIds, ?string $dataType)
    {
        return self::destroy(function ($query) use ($dataIds, $dataType) {
            $query->whereIN('dataId', $dataIds)
                ->where(['dataType' => $dataType]);
        });
    }

    /**
     * 根据课程ID获取题目列表
     *
     * @param int $courseId 课程ID
     * @return array
     */
    public function listByCourse($courseId)
    {
        return $this->where('courseId', $courseId)
            ->order('sortNum', 'asc')
            ->select()
            ->toArray();
    }

    public function getListPage(array $where, string $page = "1", int $limit = 10)
    {
        return $this->where($where)
            ->order(['sortNum' => 'asc'])
            ->paginate([
                'page' => $page,
                'list_rows' => $limit
            ]);
    }

    public function getInfo(array $where)
    {
        return $this->where($where)->find();
    }

    public function saveOrUpdate($data)
    {
        $data['answer'] = $data['answerList'] ? json_encode($data['answerList']) : [];
        $data['option'] = $data['optionList'] ? json_encode($data['optionList']) : [];
        $id = $data['id'] ?? null;
        if ($id) {
            $info = $this->where('id', $id)->find();
            if (!$info) {
                throw new ValidateException('记录不存在');
            }
            $info->save($data);
        } else {
            $this->save($data);
        }
        return true;
    }

    public function del($ids)
    {
        return self::destroy(function ($query) use ($ids) {
            $query->whereIn('id', $ids);
        });
    }


    public function importExcel($importExcelList)
    {
        $this->startTrans();
        try {
            $questionList = $importExcelList;
            $questionListCount = count($questionList);
            for ($i = 0; $i < $questionListCount; $i++) {
                $msg = "第" . ($i + 1) . "行";
                $question = $questionList[$i];
                $optionList = json_decode($question['option'], true) ?? [];
                $answerList = json_decode($question['answer'], true) ?? [];
                if (!$question['name']) {
                    throw new ValidateException($msg . "题干不能为空");
                }
                if (!$question['questionType']) {
                    throw new ValidateException($msg . "题目类型不能为空");
                }
                if (empty($optionList)) {
                    throw new ValidateException($msg . "选项不能为空");
                }
                if (empty($answerList)) {
                    throw new ValidateException($msg . "答案不能为空");
                }
                $questionType = $question['questionType'];
                if ($questionType == QuestionTypeEnum::E1) {
                    if (count($answerList) > 1) {
                        throw new ValidateException($msg . "单选题答案只能有一个");
                    }
                }
                $count = 0;
                foreach ($optionList as $option) {
                    if (in_array($option['value'], $answerList)) {
                        $count++;
                    }
                }
                if ($count != count($answerList)) {
                    throw new ValidateException($msg . "答案错误，请填写对应的选项");
                }
            }
            $this->saveAll($questionList);
            $this->commit();
        } catch (Exception|PDOException|ValidateException $e) {
            $this->rollback();
            throw new ValidateException($e->getMessage());
        }
        return true;
    }

    //-----------------------------------------------------------------------------------
    //｜                                   模型关联                                       ｜
    //-----------------------------------------------------------------------------------

}